package com.itheima.service.cargo.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.dao.cargo.*;
import com.itheima.domain.cargo.*;
import com.itheima.service.cargo.ExportService;
import com.itheima.vo.ExportProductResult;
import com.itheima.vo.ExportProductVo;
import com.itheima.vo.ExportResult;
import com.itheima.vo.ExportVo;
import org.apache.cxf.jaxrs.client.WebClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportDao exportDao; // 报运dao

    @Autowired
    private ExportProductDao exportProductDao;//报运单商品dao

    @Autowired
    private ExtEproductDao extEproductDao;  //报运单附件Dao

    @Autowired
    private ContractDao contractDao; // 合同dao

    @Autowired
    private ContractProductDao contractProductDao; //合同货物dao

    @Autowired
    private ExtCproductDao extCproductDao;  //合同附件Dao

    //保存
    public void save(Export export) {
        //0 准备合同id的集合
        List<String> contractIdList = Arrays.asList(export.getContractIds().split(","));

        //======================================查询合同,保存报运单=====================================================//
        //1 查询当前报运单下的合同
        ContractExample contractExample = new ContractExample();
        contractExample.createCriteria().andIdIn(contractIdList);
        List<Contract> contractList = contractDao.selectByExample(contractExample);

        //2 需要处理的字段: 合同号 货物数量 附件数量
        StringBuilder sb = new StringBuilder();//合同号拼接
        Integer proNum = 0;//货物
        Integer extNum = 0;//附件
        for (Contract contract : contractList) {
            sb.append(contract.getContractNo() + " ");
            proNum += contract.getProNum();
            extNum += contract.getExtNum();
        }
        export.setCustomerContract(sb.toString());
        export.setProNum(proNum);
        export.setExtNum(extNum);

        //3 保存报运单
        exportDao.insertSelective(export);


        //=================================查询合同下的货物,保存报运单下的货物=============================================//
        //1 查询当前报运单下的货物
        ContractProductExample contractProductExample = new ContractProductExample();
        contractProductExample.createCriteria().andContractIdIn(contractIdList);
        List<ContractProduct> contractProductList = contractProductDao.selectByExample(contractProductExample);

        //2 将合同下的货物数据复制到报运单下的货物种
        for (ContractProduct contractProduct : contractProductList) {
            ExportProduct exportProduct = new ExportProduct();

            //复制属性,注意两个点:1 这个工具类用的是Spring的; 2 这个复制动作要在单独赋值之前执行
            BeanUtils.copyProperties(contractProduct, exportProduct);

            //需要单独设置
            exportProduct.setId(UUID.randomUUID().toString());//id
            exportProduct.setExportId(export.getId());//exportId

            //3 保存
            exportProductDao.insertSelective(exportProduct);
        }

        //=================================查询合同下的附件,保存报运单下的附件=============================================//
        //1 查询当前报运单下的附件
        ExtCproductExample extCproductExample = new ExtCproductExample();
        extCproductExample.createCriteria().andContractIdIn(contractIdList);
        List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);

        //2 将合同下的附件数据复制到报运单下的附件
        for (ExtCproduct extCproduct : extCproductList) {
            //复制属性
            ExtEproduct extEproduct = new ExtEproduct();
            BeanUtils.copyProperties(extCproduct, extEproduct);

            //单独设置
            extEproduct.setId(UUID.randomUUID().toString());
            extEproduct.setExportId(export.getId());

            //3 保存
            extEproductDao.insertSelective(extEproduct);
        }
    }

    //更新
    public void update(Export export) {
        //========================================更新报运单====================================//
        exportDao.updateByPrimaryKeySelective(export);

        //========================================更新报运单下的货物====================================//
        for (ExportProduct exportProduct : export.getExportProducts()) {
            exportProductDao.updateByPrimaryKeySelective(exportProduct);
        }
    }

    //删除
    public void delete(String id) {
        /*=========删除报运单中的货物===========*/
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProducts = exportProductDao.selectByExample(exportProductExample);
        for (ExportProduct exportProduct : exportProducts) {
            exportProductDao.deleteByPrimaryKey(exportProduct.getId());
        }
        /*=========删除报运单中的附件===========*/
        ExtEproductExample extEproductExample = new ExtEproductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExtEproduct> extEproducts = extEproductDao.selectByExample(extEproductExample);
        for (ExtEproduct extEproduct : extEproducts) {
            extEproductDao.deleteByPrimaryKey(extEproduct.getId());
        }
        /*=========删除报运单===========*/
        exportDao.deleteByPrimaryKey(id);
    }

    //根据id查询
    public Export findById(String id) {
        return exportDao.selectByPrimaryKey(id);
    }

    //分页
    public PageInfo findByPage(int pageNum, int pageSize, ExportExample example) {
        PageHelper.startPage(pageNum, pageSize);
        List<Export> list = exportDao.selectByExample(example);
        return new PageInfo(list);
    }

    //电子报运
    @Override
    public void exportE(String id) {

        //1 查询报运单,封装海关的报运单对象
        Export export = exportDao.selectByPrimaryKey(id);
        ExportVo exportVo = new ExportVo();
        BeanUtils.copyProperties(export, exportVo);//复制属性
        exportVo.setExportId(id);//设置报运单id
        exportVo.setInputDate(new Date());//设置申批时间

        //2 查询报运单货物,封装海关的报运单货物对象
        ExportProductExample exportProductExample = new ExportProductExample();
        exportProductExample.createCriteria().andExportIdEqualTo(id);
        List<ExportProduct> exportProductList = exportProductDao.selectByExample(exportProductExample);

        for (ExportProduct exportProduct : exportProductList) {
            ExportProductVo exportProductVo = new ExportProductVo();
            BeanUtils.copyProperties(exportProduct, exportProductVo);//复制属性
            exportProductVo.setExportProductId(exportProduct.getId());//设置货物id

            exportVo.getProducts().add(exportProductVo);//将货物对象关联进报运单对象
        }


        //3 发送海关报运
        WebClient.create("http://localhost:5003/ws/export/user").post(exportVo);

        //4 修改一下当前报运单状态(0---->1)
        export.setState(1);
        exportDao.updateByPrimaryKeySelective(export);
    }

    @Override
    public void findExportResult(String id) {
        //1 调用海关平台查询
        ExportResult exportResult = WebClient.create("http://localhost:5003/ws/export/user/" + id).get(ExportResult.class);
        System.out.println(exportResult);

        //2 解析结果 : 报运结果 税

        //3 更新报运单状态
        Export export = new Export();
        export.setId(exportResult.getExportId());//id
        export.setState(exportResult.getState());//状态
        export.setRemark(exportResult.getRemark());//备注
        exportDao.updateByPrimaryKeySelective(export);//一定支持动态SQL

        //4 更新报运单下货物的税
        for (ExportProductResult product : exportResult.getProducts()) {
            ExportProduct exportProduct = new ExportProduct();
            exportProduct.setId(product.getExportProductId());
            exportProduct.setTax(product.getTax());

            exportProductDao.updateByPrimaryKeySelective(exportProduct);
        }


    }

    @Override
    public List<Export> findAll(ExportExample exportExample) {
        return exportDao.selectByExample(exportExample);
    }

    @Override
    public void onlyUpdateExport(Export export) {
        exportDao.updateByPrimaryKeySelective(export);
    }
}
